package com.coocaa.cirrus.common.third.filestore.service;

import cn.hutool.core.io.file.FileNameUtil;
import com.coocaa.cirrus.common.base.model.MetaDataModel;
import com.coocaa.cirrus.common.base.util.IdCreateUtil;
import com.coocaa.cirrus.common.base.util.MetaDataParseUtil;
import com.coocaa.cirrus.common.third.filestore.config.CosProperties;
import com.coocaa.cirrus.common.third.filestore.enums.CosEnums;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Map;

/**
 * @author bijiahao
 * @date : 2025/7/15 16:06
 * @description
 */
@Slf4j
//@Service
public class CosStorageService implements FileStorageService {
    @Autowired
    private COSClient cosClient;
    @Autowired
    private CosProperties cosProperties;
    private static final String LOCAL_DIR = System.getenv("LOCAL_UPLOAD_DIR");
    private static DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");

    @Override
    public String uploadFile(MultipartFile file) {
        String newUrl = "";
        String ext = FileNameUtil.extName(file.getOriginalFilename());
        String fileName = IdCreateUtil.getStrId() + "." + ext;
        String localDir = LOCAL_DIR;
        if (StringUtils.isBlank(localDir)) {
            localDir = cosProperties.getAigcLocalDir();
        }
        String fileLocalPath = localDir + fileName;
        try {
            // 写入文件
            File outputFile = new File(fileLocalPath);
            file.transferTo(outputFile);
            newUrl = uploadFile(fileLocalPath, CosEnums.KNOWLEDGE_DOC_COS_DIR);
        } catch (Exception e) {
            log.error("文件上传异常:", e);
        } finally {
            FileUtils.deleteQuietly(new File(fileLocalPath));
        }
        return newUrl;
    }

    public String uploadFile(String fileLocalPath, CosEnums cosEnums) throws Exception {
        LocalDate now = LocalDate.now();
        String dirPathInCos = cosEnums.getDir() + now.format(FORMATTER);
        return uploadFile(fileLocalPath, dirPathInCos);
    }

    public String uploadFile(String fileLocalPath, String fileDirInCos) throws Exception {
        long startTimeMs = System.currentTimeMillis();
        log.info(getInfo(Thread.currentThread().getId(),
                startTimeMs,
                fileLocalPath,
                fileDirInCos));
        String url = null;
        int retryNum = 2;
        fileLocalPath = fileLocalPath.replace('\\', '/');
        File file = new File(fileLocalPath);
        if (!file.exists()) {
            throw new FileNotFoundException("本地文件：" + file.getPath() + "不存在！！！");
        }
        try {
            String key = "/" + fileDirInCos + "/" + file.getName();
            for (int i = 0; i < retryNum; i++) {
                PutObjectResult putObjectResult = null;
                log.info(getInfo(i,
                        fileLocalPath,
                        key));
                try {

                    PutObjectRequest putObjectRequest = new PutObjectRequest(
                            cosProperties.getAigcBucketName(),
                            key,
                            file);
                    ObjectMetadata metadata = MetaDataParseUtil.parseObjectMetadata(file);
                    if (null != metadata) {
                        putObjectRequest.withMetadata(metadata);
                    }
                    putObjectResult = cosClient.putObject(putObjectRequest);
                    if (putObjectResult != null) {
                        url = cosProperties.getAigcUrlPrefix() + key;
                        break;
                    }
                } catch (CosClientException e) {
                    String requestId = "";
                    if (null != putObjectResult) {
                        requestId = putObjectResult.getRequestId();
                    }
                    log.error("cos上传异常requestId:" + requestId, e);
                    url = null;
                }
            }
        } catch (Exception e) {
            log.error("cos上传异常", e);
        }
        double consumeTime = (System.currentTimeMillis() - startTimeMs) / 1000d;
        log.info(getInfo(Thread.currentThread().getId(),
                startTimeMs,
                consumeTime,
                fileLocalPath,
                fileDirInCos,
                url));

        return url;
    }

    public  Map<String, String> getCOSObject(String key) {
        GetObjectMetadataRequest metaRequest = new GetObjectMetadataRequest(cosProperties.getAigcBucketName(), key);
// 触发图片信息处理
        metaRequest.putCustomQueryParameter("ci-process", "imageinfo");

        ObjectMetadata metadata = cosClient.getObjectMetadata(metaRequest);
        Map<String, String> userMeta = metadata.getUserMetadata();
        return userMeta;
    }


    private void doUpload() {

    }

    private static String getInfo(long threadId, long startTimeMs, String fileLocalPath, String fileDirInCos) {
        StringBuilder info = new StringBuilder();
        info.append("uploadFile线程id：").append(threadId).append(", 启动时间点：").append(startTimeMs)
                .append(", fileLocalPath: ").append(fileLocalPath).append(", fileDirInCos: ").append(fileDirInCos);
        return info.toString();
    }

    private static String getInfo(int i, String fileLocalPath, String key) {
        StringBuilder info = new StringBuilder();
        info.append("第").append(i).append("次，文件上传COS执行...fileLocalPath: ")
                .append(fileLocalPath).append(", key: ").append(key);
        return info.toString();
    }

    private static String getInfo(long threadId, long startTimeMs, double consumeTime, String fileLocalPath, String fileDirInCos, String url) {
        StringBuilder info = new StringBuilder();
        info.append("uploadFile线程id：").append(threadId).append(", 启动时间点：").append(startTimeMs)
                .append("程序运行耗时：").append(consumeTime).append("秒, fileLocalPath: ")
                .append(fileLocalPath).append(", fileDirInCos: ").append(fileDirInCos)
                .append(", 结果url：").append(url);
        return info.toString();
    }
}
